/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Andre Meixner
* @copyright  2017 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/


#ifndef __MMM_ViewerWindow_H_
#define __MMM_ViewerWindow_H_

#include <QList>
#include <QSettings>
#include <QMainWindow>
#include <QFrame>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/sensors/SoTimerSensor.h>

#ifndef Q_MOC_RUN
#include <MMM/Motion/MotionReaderXML.h>
#include <MMM/Motion/SensorFactory.h>
#include "PluginHandler/PluginHandler.h"
#include "PluginHandler/PluginHandlerDialog.h"
#include "SensorVisualisation/SensorVisualisationHandler.h"
#include "MotionHandler.h"
#include "MotionHandlerFactory.h"
#endif

Q_DECLARE_METATYPE(QList<float>)

namespace Ui {

class MMMViewerWindow;
}

class SegmentationDialog;

class MMMViewerWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MMMViewerWindow(QWidget* parent = 0);
    ~MMMViewerWindow();

    void showWindow();
    void progressMotion();

signals:
    void motionsOpened(bool opened);
    void timestepChanged(float timestep);

public slots:
    void jumpTo(float timestep);
    void updateMotionHandler(const std::map<std::string, boost::shared_ptr<MMM::MotionHandlerFactory> > &motionHandlerFactories);

private slots:
    bool openMotion();
    bool openMotion(const std::string &motionFilePath, bool ignoreError = false);
    bool openMotions(MMM::MotionList motions, bool ignoreError = false, const std::string &motionFilePath = std::string());
    void handleMotion(const QString &handlerName);
    void saveMotion();
    void motionSaved();
    void sliderMoved(int position);
    void fpsChanged(int newValue);
    void setVelocity(int index);
    void playStopMotion();
    void setAntiAliasing(bool value);
    void showFloor(bool value);
    void displayVisualisationTable(bool value);
    void setInterpolationEnabled(bool value);
    void saveScreenshot(float timestep, const std::string &directory, const std::string &name = std::string());
    void closeEvent(QCloseEvent *event);
    bool closeWindow();
    void sensorVisualisationLoaded(bool loaded);

private:
    static SoSeparator* createSceneGraph();
    static SoSwitch* createFloorVisualisation(SoSeparator* sceneGraph);
    void addMotionMenu();
    void addOptionMenu();
    static void progressTimerCallback(void* data, SoSensor* sensor);
    void setupViewer();
    void setupCamera();
    void setupVelocityComboBox();
    bool calculateTimesteps(MMM::MotionList motions);
    void stopTimer();
    bool replaceMotion(MMM::MotionPtr motion);
    void setTitle(const std::string &motionFilePath = std::string());
    void errorMessageBox(const std::string &message);
    void loadLastMotionFile();
    void updateMotion(const std::map<std::string, boost::shared_ptr<MMM::SensorFactory> > &sensorFactories);
    void saveCameraSettings();
    void createTimestampString();
    void saveMotionBackup();

    QMenu* importMotionMenu;
    QMenu* exportMotionMenu;
    QMenu* addSensorMenu;
    QMenu* generalMenu;

    SoSeparator* sceneGraph;
    SoSwitch* floorVisualisation;
    SoTimerSensor* progressTimer;

    PluginHandlerDialog* pluginHandlerDialog;
    SensorVisualisationHandlerPtr sensorVisualisationHandler;
    std::map<std::string, MMM::MotionHandlerPtr> motionHandler;
    MMM::MotionReaderXMLPtr motionReader;
    MMM::MotionList motions;
    bool motionChanged;
    std::string timestamp;

    float minTimestep;
    float maxTimestep;
    int framesPerSecond;
    float currentTimestep;
    float lastTimestep;
    float velocity;

    QSettings settings;

    Ui::MMMViewerWindow* ui;
    SoQtExaminerViewer* viewer;
};

#endif // __MMM_ViewerWindow_H_
